package com.cantuaria.jsf.control.support;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import org.apache.log4j.Logger;

import com.cantuaria.jsf.dao.impl.Dao;


/** Classe Genérica de Controle
 *  @Autor: Flávio CANTUÁRIA
 *  <h4>Descrição</h4>
 *  <br>
 *  Classe dedicada a simplificar o controle com os métodos CRUD básicos 
 */


public abstract class GenericControl<T> {
	
	protected T instance;
	protected Dao<T> dao;
	protected Logger log;
	
	/**
	 * Método salva a instancia e manda uma mensagem pelo contexto
	 * @param msg -> Mensagem apresentada no contexto
	 */
	public void salvar(String msg){
		try{
			dao.saveOrUpdate(instance);
			FacesContext context = FacesContext.getCurrentInstance();
        	context.addMessage(null, new FacesMessage(msg));
		}catch (Exception e) {
			log.error("Erro ao mandar salvar a instancia "+e);
		}
	}


	/**
	 * Método que recebe um parametro vindo do contexto ex: "PessoaId"
	 * Para que seja buscado o objeto dessa id
	 * @param param é o parametro que foi passado no contexto usando as tags:
	 * <f:param name="PessoaId" value="#{instancia.id}" /> 
	 * @return Retorna a instancia encontrada no banco, caso não encotre retorna null
	 */
	public T instanceForEdit(String param){
		try{
			String id = (String) FacesContext.getCurrentInstance()
   											 .getExternalContext()
											 .getRequestParameterMap()
											 .get(param); 
			//Ao recuperar a instancia é preciso setála na variavel instance
			instance = dao.consultarId(Integer.parseInt(id));
			return instance;
		}catch (Exception e) {
			log.error("Erro ao mandar recuperar a instancia "+e);
			return null;
		}
	}
	
	
	/**
	 * Método que recebe um parametro vindo do contexto ex: "PessoaId"
	 * Para que seja apagado o objeto com essa id
	 * @param param é o parametro que foi passado no contexto usando as tags:
	 * <f:param name="PessoaId" value="#{instancia.id}" /> 
	 */
	public void deletar(String param){
		try{
			FacesContext context = FacesContext.getCurrentInstance();
			String id = FacesContext.getCurrentInstance()
											 .getExternalContext()
											 .getRequestParameterMap()
											 .get(param);
			dao.deletar(Integer.parseInt(id));
			context.addMessage(null, new FacesMessage("Deletado com sucesso!"));
		}catch (Exception e) {
			log.error("Erro ao mandar deletar a instancia "+e);
		}
	}
	
	/**
	 * Metodo que deve criar a instancia de quem extender essa classe
	 * @return Retorna uma instancia ex: new Pessoa();
	 */
	public abstract T createInstance();
	
	/**
	 * Metodo que obriga o CRUD de ter um botão limpar
	 */
	public abstract void limpar();
	
	/**
	 * Metodo que cria e retorna uma instancia caso não haja uma
	 * @return Retorna uma instancia não nulla.
	 */
	public T getInstance() {
		if(instance == null){
			return createInstance();
		}else{
			return instance;
		}
	}

	public void setInstance(T instance) {
		this.instance = instance;
	}
}
